<!DOCTYPE html>
<html lang="zh-CN">





<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/blog/img/favicon.png">
  <link rel="icon" type="image/png" href="/blog/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
  
  <meta name="theme-color" content="#35495e">
  <meta name="description" content="小菜头的博客，主要记录学习笔记，包含：html,css,javascript,jQuery,vue等">
  <meta name="author" content="A-cai">
  <meta name="keywords" content="html,css,javascript,jQuery,vue">
  <title>前端开发规范 - A-cai的blog</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/blog/lib/hint/hint.min.css" />

  
    <link  rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/10.0.0/styles/atom-one-dark.min.css" />
  

  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_yg9cfy8wd6.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_pjno9b9zyxs.css">


<link  rel="stylesheet" href="/blog/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script  src="/blog/js/utils.js" ></script>
<meta name="generator" content="Hexo 4.2.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/blog/">&nbsp;<strong>A-cai的学习笔记</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/blog/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner intro-2" id="background" parallax=true
         style="background: url('/blog/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="container text-center white-text fade-in-up">
            <span class="h2" id="subtitle">
              
            </span>

            
              
  <div class="mt-3 post-meta">
    <i class="iconfont icon-date-fill" aria-hidden="true"></i>
    <time datetime="2020-06-26 14:12">
      2020年6月26日 下午
    </time>
  </div>


<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      5.7k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      75
       分钟
    </span>
  

  
  
    
      <!-- 不蒜子统计文章PV -->
      <span id="busuanzi_container_page_pv" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="busuanzi_value_page_pv"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5" id="board">
          <div class="post-content mx-auto" id="post">
            
              <p class="note note-info">
                
                  本文最后更新于：2020年4月26日 中午
                
              </p>
            
            <article class="markdown-body">
              <h2 id="前端代码规范"><a href="#前端代码规范" class="headerlink" title="前端代码规范"></a>前端代码规范</h2><p>Front Standard Guide</p>
<h2 id="前端-JS-项目开发规范"><a href="#前端-JS-项目开发规范" class="headerlink" title="前端 JS 项目开发规范"></a>前端 JS 项目开发规范</h2><p>规范的目的是为了编写高质量的代码，让你的团队成员每天的心情都是愉悦的，大家在一起是快乐的。</p>
<blockquote>
<p><strong>引自《阿里规约》的开头片段：</strong></p>
<p>现代软件架构的复杂性需要协同开发完成，如何高效地协同呢？无规矩不成方圆，无规范难以协同，比如，制订交通法规表面上是要限制行车权，实际上是保障公众的人身安全，试想如果没有限速，没有红绿灯，谁还敢上路行驶。对软件来说，适当的规范和标准绝不是消灭代码内容的创造性、优雅性，而是限制过度个性化，以一种普遍认可的统一方式一起做事，提升协作效率，降低沟通成本。代码的字里行间流淌的是软件系统的血液，质量的提升是尽可能少踩坑，杜绝踩重复的坑，切实提升系统稳定性，码出质量。</p>
</blockquote>
<h2 id="一、编程规约"><a href="#一、编程规约" class="headerlink" title="一、编程规约"></a>一、编程规约</h2><h3 id="一-命名规范"><a href="#一-命名规范" class="headerlink" title="(一)命名规范"></a>(一)命名规范</h3><h4 id="1-1-1-项目命名"><a href="#1-1-1-项目命名" class="headerlink" title="1.1.1 项目命名"></a>1.1.1 项目命名</h4><p>全部采用小写方式， 以中划线分隔。</p>
<p>正例：<code>mall-management-system</code></p>
<p>反例：<code>mall_management-system / mallManagementSystem</code></p>
<h4 id="1-1-2-目录命名"><a href="#1-1-2-目录命名" class="headerlink" title="1.1.2 目录命名"></a>1.1.2 目录命名</h4><p>全部采用小写方式， 以中划线分隔，有复数结构时，要采用复数命名法， 缩写不用复数</p>
<p>正例： <code>scripts / styles / components / images / utils / layouts / demo-styles / demo-scripts / img / doc</code></p>
<p>反例： <code>script / style / demo_scripts / demoStyles / imgs / docs</code></p>
<p>【特殊】VUE 的项目中的 components 中的组件目录，使用 kebab-case 命名</p>
<p>正例： <code>head-search / page-loading / authorized / notice-icon</code></p>
<p>反例： <code>HeadSearch / PageLoading</code></p>
<p>【特殊】VUE 的项目中的除 components 组件目录外的所有目录也使用 kebab-case 命名<br>正例： <code>page-one / shopping-car / user-management</code></p>
<p>反例： <code>ShoppingCar / UserManagement</code></p>
<h4 id="1-1-3-JS、CSS、SCSS、HTML、PNG-文件命名"><a href="#1-1-3-JS、CSS、SCSS、HTML、PNG-文件命名" class="headerlink" title="1.1.3 JS、CSS、SCSS、HTML、PNG 文件命名"></a>1.1.3 JS、CSS、SCSS、HTML、PNG 文件命名</h4><p>全部采用小写方式， 以中划线分隔</p>
<p>正例： <code>render-dom.js / signup.css / index.html / company-logo.png</code></p>
<p>反例： <code>renderDom.js / UserManagement.html</code></p>
<h4 id="1-1-4-命名严谨性"><a href="#1-1-4-命名严谨性" class="headerlink" title="1.1.4 命名严谨性"></a>1.1.4 命名严谨性</h4><p>代码中的命名严禁使用拼音与英文混合的方式，更不允许直接使用中文的方式。 说明：正确的英文拼写和语法可以让阅读者易于理解，避免歧义。注意，即使纯拼音命名方式也要避免采用</p>
<p>正例：<code>henan / luoyang / rmb 等国际通用的名称，可视同英文。</code></p>
<p>反例：<code>DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3</code></p>
<p><strong>杜绝完全不规范的缩写，避免望文不知义：</strong></p>
<p>反例：AbstractClass“缩写”命名成 AbsClass；condition“缩写”命名成 condi，此类随意缩写严重降低了代码的可阅读性。</p>
<h3 id="二-HTML-规范-（Vue-Template-同样适用）"><a href="#二-HTML-规范-（Vue-Template-同样适用）" class="headerlink" title="(二)HTML 规范 （Vue Template 同样适用）"></a>(二)HTML 规范 （Vue Template 同样适用）</h3><h4 id="1-2-1-HTML-类型"><a href="#1-2-1-HTML-类型" class="headerlink" title="1.2.1 HTML 类型"></a>1.2.1 HTML 类型</h4><p>推荐使用 HTML5 的文档类型申明： .<br>（建议使用 text/html 格式的 HTML。避免使用 XHTML。XHTML 以及它的属性，比如 application/xhtml+xml 在浏览器中的应用支持与优化空间都十分有限）。</p>
<ul>
<li>规定字符编码</li>
<li>IE 兼容模式</li>
<li>规定字符编码</li>
<li>doctype 大写</li>
</ul>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=Edge"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Page title<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"images/company-logo.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Company"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></code></pre></div>

<h4 id="1-2-2-缩进"><a href="#1-2-2-缩进" class="headerlink" title="1.2.2 缩进"></a>1.2.2 缩进</h4><p>缩进使用 2 个空格（一个 tab）</p>
<p>嵌套的节点应该缩进。</p>
<h4 id="1-2-3-分块注释"><a href="#1-2-3-分块注释" class="headerlink" title="1.2.3 分块注释"></a>1.2.3 分块注释</h4><p>在每一个块状元素，列表元素和表格元素后，加上一对 HTML 注释。注释格式</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 英文 中文 start &gt;</span>
<span class="hljs-comment"></span>
<span class="hljs-comment">&lt;!-- 英文 中文 end &gt;</span></code></pre></div>

<p>正例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- header 头部 start --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>
        <span class="hljs-comment">&lt;!-- 图片会把a标签给撑开，所以不用设置a标签的大小 --&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"images/header.jpg"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- header 头部 end --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></code></pre></div>

<h3 id="1-2-4-语义化标签"><a href="#1-2-4-语义化标签" class="headerlink" title="1.2.4 语义化标签"></a>1.2.4 语义化标签</h3><p>HTML5 中新增很多语义化标签，所以优先使用语义化标签，避免一个页面都是 div 或者 p 标签</p>
<p>正例</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span></code></pre></div>

<p>反例</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></code></pre></div>

<h4 id="1-2-5-引号"><a href="#1-2-5-引号" class="headerlink" title="1.2.5 引号"></a>1.2.5 引号</h4><p>使用双引号(“ “) 而不是单引号(’ ‘) 。</p>
<p>正例： <code>&quot; &quot;</code></p>
<p>反例： <code>’ &#39;</code></p>
<h3 id="三-CSS-规范"><a href="#三-CSS-规范" class="headerlink" title="(三) CSS 规范"></a>(三) CSS 规范</h3><h4 id="1-3-1-命名"><a href="#1-3-1-命名" class="headerlink" title="1.3.1 命名"></a>1.3.1 命名</h4><ul>
<li>类名使用小写字母，以中划线分隔</li>
<li>id 采用驼峰式命名</li>
<li>scss 中的变量、函数、混合、placeholder 采用驼峰式命名</li>
</ul>
<p>ID 和 class 的名称总是使用可以反应元素目的和用途的名称，或其他通用的名称，代替表象和晦涩难懂的名称</p>
<p>不推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.fw-800</span> &#123;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">800</span>;
&#125;

<span class="hljs-selector-class">.red</span> &#123;
  <span class="hljs-attribute">color</span>: red;
&#125;</code></pre></div>

<p>推荐:</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.heavy</span> &#123;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">800</span>;
&#125;

<span class="hljs-selector-class">.important</span> &#123;
  <span class="hljs-attribute">color</span>: red;
&#125;</code></pre></div>

<h4 id="1-3-2-选择器"><a href="#1-3-2-选择器" class="headerlink" title="1.3.2 选择器"></a>1.3.2 选择器</h4><p>1)css 选择器中避免使用标签名<br>从结构、表现、行为分离的原则来看，应该尽量避免 css 中出现 HTML 标签，并且在 css 选择器中出现标签名会存在潜在的问题。</p>
<p>2)很多前端开发人员写选择器链的时候不使用 直接子选择器（注：直接子选择器和后代选择器的区别）。有时，这可能会导致疼痛的设计问题并且有时候可能会很耗性能。然而，在任何情况下，这是一个非常不好的做法。如果你不写很通用的，需要匹配到 DOM 末端的选择器， 你应该总是考虑直接子选择器。</p>
<p>不推荐:</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.content</span> <span class="hljs-selector-class">.title</span> &#123;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2rem</span>;
&#125;</code></pre></div>

<p>推荐:</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.content</span> &gt; <span class="hljs-selector-class">.title</span> &#123;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2rem</span>;
&#125;</code></pre></div>

<h4 id="1-3-3-尽量使用缩写属性"><a href="#1-3-3-尽量使用缩写属性" class="headerlink" title="1.3.3 尽量使用缩写属性"></a>1.3.3 尽量使用缩写属性</h4><p>不推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">border-top-style</span>: <span class="hljs-selector-tag">none</span>;
<span class="hljs-selector-tag">font-family</span>: <span class="hljs-selector-tag">palatino</span>, <span class="hljs-selector-tag">georgia</span>, <span class="hljs-selector-tag">serif</span>;
<span class="hljs-selector-tag">font-size</span>: 100%;
<span class="hljs-selector-tag">line-height</span>: 1<span class="hljs-selector-class">.6</span>;
<span class="hljs-selector-tag">padding-bottom</span>: 2<span class="hljs-selector-tag">em</span>;
<span class="hljs-selector-tag">padding-left</span>: 1<span class="hljs-selector-tag">em</span>;
<span class="hljs-selector-tag">padding-right</span>: 1<span class="hljs-selector-tag">em</span>;
<span class="hljs-selector-tag">padding-top</span>: 0;</code></pre></div>

<p>推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">border-top</span>: 0;
font: 100%/1.6 palatino, georgia, serif;
<span class="hljs-selector-tag">padding</span>: 0 1<span class="hljs-selector-tag">em</span> 2<span class="hljs-selector-tag">em</span>;</code></pre></div>

<h4 id="1-3-4-每个选择器及属性独占一行"><a href="#1-3-4-每个选择器及属性独占一行" class="headerlink" title="1.3.4 每个选择器及属性独占一行"></a>1.3.4 每个选择器及属性独占一行</h4><p>不推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">button</span>&#123;
  <span class="hljs-attribute">width</span>:<span class="hljs-number">100px</span>;<span class="hljs-attribute">height</span>:<span class="hljs-number">50px</span>;<span class="hljs-attribute">color</span>:<span class="hljs-number">#fff</span>;<span class="hljs-attribute">background</span>:<span class="hljs-number">#00a0e9</span>;
&#125;</code></pre></div>

<p>推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">button</span>&#123;
  <span class="hljs-attribute">width</span>:<span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>:<span class="hljs-number">50px</span>;
  <span class="hljs-attribute">color</span>:<span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">background</span>:<span class="hljs-number">#00a0e9</span>;
&#125;</code></pre></div>

<h4 id="1-3-5-省略-0-后面的单位"><a href="#1-3-5-省略-0-后面的单位" class="headerlink" title="1.3.5 省略 0 后面的单位"></a>1.3.5 省略 0 后面的单位</h4><p>不推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">div</span>&#123;
  <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">0px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0em</span>;
&#125;</code></pre></div>

<p>推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">div</span>&#123;
  <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
&#125;</code></pre></div>

<h4 id="1-3-6-避免使用-ID-选择器及全局标签选择器防止污染全局样式"><a href="#1-3-6-避免使用-ID-选择器及全局标签选择器防止污染全局样式" class="headerlink" title="1.3.6 避免使用 ID 选择器及全局标签选择器防止污染全局样式"></a>1.3.6 避免使用 ID 选择器及全局标签选择器防止污染全局样式</h4><p>不推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-id">#header</span>&#123;
  <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">0px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0em</span>;
&#125;</code></pre></div>

<p>推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.header</span>&#123;
  <span class="hljs-attribute">padding-bottom</span>: <span class="hljs-number">0px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0em</span>;
&#125;</code></pre></div>

<h3 id="四-LESS-规范"><a href="#四-LESS-规范" class="headerlink" title="(四) LESS 规范"></a>(四) LESS 规范</h3><h4 id="1-4-1-代码组织"><a href="#1-4-1-代码组织" class="headerlink" title="1.4.1 代码组织"></a>1.4.1 代码组织</h4><h5 id="1-将公共-less-文件放置在-style-less-common-文件夹"><a href="#1-将公共-less-文件放置在-style-less-common-文件夹" class="headerlink" title="1)将公共 less 文件放置在 style/less/common 文件夹"></a>1)将公共 less 文件放置在 style/less/common 文件夹</h5><p>例:// color.less,common.less</p>
<h5 id="2-按以下顺序组织"><a href="#2-按以下顺序组织" class="headerlink" title="2)按以下顺序组织"></a>2)按以下顺序组织</h5><p>1、@import;<br>2、变量声明;<br>3、样式声明;</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-keyword">@import</span> <span class="hljs-string">"mixins/size.less"</span>;

@default-text-color: #333;

<span class="hljs-selector-class">.page</span> &#123;
  <span class="hljs-attribute">width</span>: <span class="hljs-number">960px</span>;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
&#125;</code></pre></div>

<h4 id="1-4-2-避免嵌套层级过多"><a href="#1-4-2-避免嵌套层级过多" class="headerlink" title="1.4.2 避免嵌套层级过多"></a>1.4.2 避免嵌套层级过多</h4><p>将嵌套深度限制在 3 级。对于超过 4 级的嵌套，给予重新评估。这可以避免出现过于详实的 CSS 选择器。<br>避免大量的嵌套规则。当可读性受到影响时，将之打断。推荐避免出现多于 20 行的嵌套规则出现</p>
<p>不推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.main</span>&#123;
  .title&#123;
    <span class="hljs-selector-class">.name</span>&#123;
       <span class="hljs-attribute">color</span>:<span class="hljs-number">#fff</span>
    &#125;
  &#125;
&#125;</code></pre></div>

<p>推荐：</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-class">.main-title</span>&#123;
   .name&#123;
      <span class="hljs-selector-tag">color</span>:<span class="hljs-selector-id">#fff</span>
   &#125;
&#125;</code></pre></div>

<h3 id="五-Javascript-规范"><a href="#五-Javascript-规范" class="headerlink" title="(五) Javascript 规范"></a>(五) Javascript 规范</h3><h4 id="1-5-1-命名"><a href="#1-5-1-命名" class="headerlink" title="1.5.1 命名"></a>1.5.1 命名</h4><h5 id="1-采用小写驼峰命名-lowerCamelCase，代码中的命名均不能以下划线，也不能以下划线或美元符号结束"><a href="#1-采用小写驼峰命名-lowerCamelCase，代码中的命名均不能以下划线，也不能以下划线或美元符号结束" class="headerlink" title="1) 采用小写驼峰命名 lowerCamelCase，代码中的命名均不能以下划线，也不能以下划线或美元符号结束"></a>1) 采用小写驼峰命名 lowerCamelCase，代码中的命名均不能以下划线，也不能以下划线或美元符号结束</h5><p>反例： <code>_name / name_ / name$</code></p>
<h5 id="2-方法名、参数名、成员变量、局部变量都统一使用-lowerCamelCase-风格，必须遵从驼峰形式。"><a href="#2-方法名、参数名、成员变量、局部变量都统一使用-lowerCamelCase-风格，必须遵从驼峰形式。" class="headerlink" title="2) 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格，必须遵从驼峰形式。"></a>2) 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格，必须遵从驼峰形式。</h5><p>正例： <code>localValue / getHttpMessage() / inputUserId</code></p>
<p>其中 method 方法命名必须是 动词 或者 动词+名词 形式</p>
<p>正例：<code>saveShopCarData /openShopCarInfoDialog</code></p>
<p>反例：<code>save / open / show / go</code></p>
<p>特此说明，增删查改，详情统一使用如下 5 个单词，不得使用其他（目的是为了统一各个端）</p>
<div class="hljs"><pre><code class="hljs css">add / update / delete / detail / get</code></pre></div>

<h3 id="附：-函数方法常用的动词"><a href="#附：-函数方法常用的动词" class="headerlink" title="附： 函数方法常用的动词:"></a>附： 函数方法常用的动词:</h3><div class="hljs"><pre><code class="hljs css">get 获取/set 设置,
add 增加/remove 删除
create 创建/destory 移除
start 启动/stop 停止
open 打开/close 关闭,
read 读取/write 写入
load 载入/save 保存,
create 创建/destroy 销毁
begin 开始/end 结束,
backup 备份/restore 恢复
import 导入/export 导出,
split 分割/merge 合并
inject 注入/extract 提取,
attach 附着/detach 脱离
bind 绑定/separate 分离,
view 查看/browse 浏览
edit 编辑/modify 修改,
select 选取/mark 标记
copy 复制/paste 粘贴,
undo 撤销/redo 重做
insert 插入/delete 移除,
add 加入/append 添加
clean 清理/clear 清除,
index 索引/sort 排序
find 查找/search 搜索,
increase 增加/decrease 减少
play 播放/pause 暂停,
launch 启动/run 运行
compile 编译/execute 执行,
debug 调试/trace 跟踪
observe 观察/listen 监听,
build 构建/publish 发布
input 输入/output 输出,
encode 编码/decode 解码
encrypt 加密/decrypt 解密,
compress 压缩/decompress 解压缩
pack 打包/unpack 解包,
parse 解析/emit 生成
connect 连接/disconnect 断开,
send 发送/receive 接收
download 下载/upload 上传,
refresh 刷新/synchronize 同步
update 更新/revert 复原,
lock 锁定/unlock 解锁
check out 签出/check in 签入,
submit 提交/commit 交付
push 推/pull 拉,
expand 展开/collapse 折叠
begin 起始/end 结束,
start 开始/finish 完成
enter 进入/exit 退出,
abort 放弃/quit 离开
obsolete 废弃/depreciate 废旧,
collect 收集/aggregate 聚集</code></pre></div>

<h5 id="3-常量命名全部大写，单词间用下划线隔开，力求语义表达完整清楚，不要嫌名字长。"><a href="#3-常量命名全部大写，单词间用下划线隔开，力求语义表达完整清楚，不要嫌名字长。" class="headerlink" title="3) 常量命名全部大写，单词间用下划线隔开，力求语义表达完整清楚，不要嫌名字长。"></a>3) 常量命名全部大写，单词间用下划线隔开，力求语义表达完整清楚，不要嫌名字长。</h5><p>正例： <code>MAX_STOCK_COUNT</code></p>
<p>反例： <code>MAX_COUNT</code></p>
<h4 id="1-5-2-代码格式"><a href="#1-5-2-代码格式" class="headerlink" title="1.5.2 代码格式"></a>1.5.2 代码格式</h4><h5 id="1-使用-2-个空格进行缩进"><a href="#1-使用-2-个空格进行缩进" class="headerlink" title="1) 使用 2 个空格进行缩进"></a>1) 使用 2 个空格进行缩进</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs js"><span class="hljs-keyword">if</span> (x &lt; y) &#123;
  x += <span class="hljs-number">10</span>;
&#125; <span class="hljs-keyword">else</span> &#123;
  x += <span class="hljs-number">1</span>;
&#125;</code></pre></div>

<h5 id="2-不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。"><a href="#2-不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。" class="headerlink" title="2) 不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。"></a>2) 不同逻辑、不同语义、不同业务的代码之间插入一个空行分隔开来以提升可读性。</h5><blockquote>
<p>说明：任何情形，没有必要插入多个空行进行隔开。</p>
</blockquote>
<h4 id="1-5-3-字符串"><a href="#1-5-3-字符串" class="headerlink" title="1.5.3 字符串"></a>1.5.3 字符串</h4><p>统一使用单引号(‘)，不使用双引号(“)。这在创建 HTML 字符串非常有好处：</p>
<p>正例:</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> str = <span class="hljs-string">'foo'</span>;
<span class="hljs-keyword">let</span> testDiv = <span class="hljs-string">'&lt;div id="test"&gt;&lt;/div&gt;'</span>;</code></pre></div>

<p>反例:</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> str = <span class="hljs-string">'foo'</span>;
<span class="hljs-keyword">let</span> testDiv = <span class="hljs-string">"&lt;div id='test'&gt;&lt;/div&gt;"</span>;</code></pre></div>

<h4 id="1-5-4-对象声明"><a href="#1-5-4-对象声明" class="headerlink" title="1.5.4 对象声明"></a>1.5.4 对象声明</h4><h5 id="1-使用字面值创建对象"><a href="#1-使用字面值创建对象" class="headerlink" title="1)使用字面值创建对象"></a>1)使用字面值创建对象</h5><p>正例： <code>let user = {};</code></p>
<p>反例： <code>let user = new Object();</code></p>
<h5 id="2-使用字面量来代替对象构造器"><a href="#2-使用字面量来代替对象构造器" class="headerlink" title="2) 使用字面量来代替对象构造器"></a>2) 使用字面量来代替对象构造器</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> user = &#123;
  age: <span class="hljs-number">0</span>,
  name: <span class="hljs-number">1</span>,
  city: <span class="hljs-number">3</span>
&#125;;</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> user = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Object</span>();
user.age = <span class="hljs-number">0</span>;
user.name = <span class="hljs-number">0</span>;
user.city = <span class="hljs-number">0</span>;</code></pre></div>

<h4 id="1-5-5-使用-ES6-7"><a href="#1-5-5-使用-ES6-7" class="headerlink" title="1.5.5 使用 ES6,7"></a>1.5.5 使用 ES6,7</h4><p>必须优先使用 ES6,7 中新增的语法糖和函数。这将简化你的程序，并让你的代码更加灵活和可复用。</p>
<blockquote>
<p>必须强制使用 ES6, ES7 的新语法，比如箭头函数、await/async ， 解构， let ， for…of 等等</p>
</blockquote>
<h4 id="1-5-6-括号"><a href="#1-5-6-括号" class="headerlink" title="1.5.6 括号"></a>1.5.6 括号</h4><p>下列关键字后必须有大括号（即使代码块的内容只有一行）：if, else, for, while, do, switch, try, catch, finally, with。</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (condition) &#123;
  doSomething();
&#125;</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (condition) doSomething();</code></pre></div>

<h4 id="1-5-7-undefined-判断"><a href="#1-5-7-undefined-判断" class="headerlink" title="1.5.7 undefined 判断"></a>1.5.7 undefined 判断</h4><p>永远不要直接使用 undefined 进行变量判断；使用 typeof 和字符串’undefined’对变量进行判断。</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> person === <span class="hljs-string">'undefined'</span>) &#123;
    ...
&#125;</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">if</span> (person === <span class="hljs-literal">undefined</span>) &#123;
    ...
&#125;</code></pre></div>

<h4 id="1-5-8-条件判断和循环最多三层"><a href="#1-5-8-条件判断和循环最多三层" class="headerlink" title="1.5.8 条件判断和循环最多三层"></a>1.5.8 条件判断和循环最多三层</h4><p>条件判断能使用三目运算符和逻辑运算符解决的，就不要使用条件判断，但是谨记不要写太长的三目运算符。如果超过 3 层请抽成函数，并写清楚注释。</p>
<h4 id="1-5-9-this-的转换命名"><a href="#1-5-9-this-的转换命名" class="headerlink" title="1.5.9 this 的转换命名"></a>1.5.9 this 的转换命名</h4><p>对上下文 this 的引用只能使用’self’来命名</p>
<h4 id="1-5-10-慎用-console-log"><a href="#1-5-10-慎用-console-log" class="headerlink" title="1.5.10 慎用 console.log"></a>1.5.10 慎用 console.log</h4><p>因 console.log 大量使用会有性能问题，所以在非 webpack 项目中谨慎使用 log 功能</p>
<h2 id="二、Vue-项目规范"><a href="#二、Vue-项目规范" class="headerlink" title="二、Vue 项目规范"></a>二、Vue 项目规范</h2><h3 id="一-Vue-编码基础"><a href="#一-Vue-编码基础" class="headerlink" title="(一) Vue 编码基础"></a>(一) Vue 编码基础</h3><p>vue 项目规范以 Vue 官方规范 （<a href="https://cn.vuejs.org/v2/style-guide/）" target="_blank" rel="noopener">https://cn.vuejs.org/v2/style-guide/）</a> 中的 A 规范为基础，在其上面进行项目开发，故所有代码均遵守该规范。</p>
<blockquote>
<p>请仔仔细细阅读 Vue 官方规范，切记，此为第一步。</p>
</blockquote>
<h4 id="2-1-1-组件规范"><a href="#2-1-1-组件规范" class="headerlink" title="2.1.1. 组件规范"></a>2.1.1. 组件规范</h4><h5 id="1-组件名为多个单词。"><a href="#1-组件名为多个单词。" class="headerlink" title="1) 组件名为多个单词。"></a>1) 组件名为多个单词。</h5><p>组件名应该始终是多个单词组成（大于等于 2），且命名规范为<code>KebabCase</code>格式。<br>这样做可以避免跟现有的以及未来的 HTML 元素相冲突，因为所有的 HTML 元素名称都是单个单词的。</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;
  name: <span class="hljs-string">'TodoItem'</span>
  <span class="hljs-comment">// ...</span>
&#125;;</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;
  name: <span class="hljs-string">'Todo'</span>,
  <span class="hljs-comment">// ...</span>
&#125;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;
  name: <span class="hljs-string">'todo-item'</span>,
  <span class="hljs-comment">// ...</span>
&#125;</code></pre></div>

<h5 id="2-组件文件名为-pascal-case-格式"><a href="#2-组件文件名为-pascal-case-格式" class="headerlink" title="2) 组件文件名为 pascal-case 格式"></a>2) 组件文件名为 pascal-case 格式</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript">components/
|- my-component.vue</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript">components/
|- myComponent.vue
|- MyComponent.vue</code></pre></div>

<h5 id="3-基础组件文件名为-base-开头，使用完整单词而不是缩写。"><a href="#3-基础组件文件名为-base-开头，使用完整单词而不是缩写。" class="headerlink" title="3) 基础组件文件名为 base 开头，使用完整单词而不是缩写。"></a>3) 基础组件文件名为 base 开头，使用完整单词而不是缩写。</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript">components/
|- base-button.vue
|- base-table.vue
|- base-icon.vue</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript">components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue</code></pre></div>

<h5 id="4-和父组件紧密耦合的子组件应该以父组件名作为前缀命名"><a href="#4-和父组件紧密耦合的子组件应该以父组件名作为前缀命名" class="headerlink" title="4) 和父组件紧密耦合的子组件应该以父组件名作为前缀命名"></a>4) 和父组件紧密耦合的子组件应该以父组件名作为前缀命名</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript">components/
|- todo-list.vue
|- todo-list-item.vue
|- todo-list-item-button.vue
|- user-profile-options.vue （完整单词）</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript">components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
|- UProfOpts.vue （使用了缩写）</code></pre></div>

<h5 id="5-在-Template-模版中使用组件，应使用-PascalCase-模式，并且使用自闭合组件。"><a href="#5-在-Template-模版中使用组件，应使用-PascalCase-模式，并且使用自闭合组件。" class="headerlink" title="5) 在 Template 模版中使用组件，应使用 PascalCase 模式，并且使用自闭合组件。"></a>5) 在 Template 模版中使用组件，应使用 PascalCase 模式，并且使用自闭合组件。</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 在单文件组件、字符串模板和 JSX 中 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">MyComponent</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">Row</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">:column</span>=<span class="hljs-string">"data"</span>/&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">Row</span>&gt;</span></code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">my-component</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">row</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">table</span> <span class="hljs-attr">:column</span>=<span class="hljs-string">"data"</span>/&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">row</span>&gt;</span></code></pre></div>

<h5 id="6-组件的-data-必须是一个函数"><a href="#6-组件的-data-必须是一个函数" class="headerlink" title="6) 组件的 data 必须是一个函数"></a>6) 组件的 data 必须是一个函数</h5><p>当在组件中使用 data 属性的时候 (除了 new Vue 外的任何地方)，它的值必须是返回一个对象的函数。 因为如果直接是一个对象的话，子组件之间的属性值会互相影响。</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;
  data () &#123;
    <span class="hljs-keyword">return</span> &#123;
      name: <span class="hljs-string">'jack'</span>
    &#125;
  &#125;
&#125;</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;
  data: &#123;
    name: <span class="hljs-string">'jack'</span>
  &#125;
&#125;</code></pre></div>

<h5 id="7-Prop-定义应该尽量详细"><a href="#7-Prop-定义应该尽量详细" class="headerlink" title="7) Prop 定义应该尽量详细"></a>7) Prop 定义应该尽量详细</h5><ul>
<li>必须使用 camelCase 驼峰命名</li>
<li>必须指定类型</li>
<li>必须加上注释，表明其含义</li>
<li>必须加上 required 或者 default，两者二选其一</li>
<li>如果有业务需要，必须加上 validator 验证</li>
</ul>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"> props: &#123;
  <span class="hljs-comment">// 组件状态，用于控制组件的颜色</span>
   status: &#123;
     type: <span class="hljs-built_in">String</span>,
     required: <span class="hljs-literal">true</span>,
     validator: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value</span>) </span>&#123;
       <span class="hljs-keyword">return</span> [
         <span class="hljs-string">'succ'</span>,
         <span class="hljs-string">'info'</span>,
         <span class="hljs-string">'error'</span>
       ].indexOf(value) !== <span class="hljs-number">-1</span>
     &#125;
   &#125;,
    <span class="hljs-comment">// 用户级别，用于显示皇冠个数</span>
   userLevel：&#123;
      type: <span class="hljs-built_in">String</span>,
      required: <span class="hljs-literal">true</span>
   &#125;
&#125;</code></pre></div>

<h5 id="8-为组件样式设置作用域"><a href="#8-为组件样式设置作用域" class="headerlink" title="8) 为组件样式设置作用域"></a>8) 为组件样式设置作用域</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript">&lt;template&gt;
  &lt;button <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"btn btn-close"</span>&gt;X&lt;<span class="hljs-regexp">/button&gt;</span>
<span class="hljs-regexp">&lt;/</span>template&gt;

&lt;!-- 使用 <span class="hljs-string">`scoped`</span> 特性 --&gt;
&lt;style scoped&gt;
  .btn-close &#123;
    background-color: red;
  &#125;
&lt;<span class="hljs-regexp">/style&gt;</span></code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-close"</span>&gt;</span>X<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-comment">&lt;!-- 没有使用 `scoped` 特性 --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span>
<span class="css">  <span class="hljs-selector-class">.btn-close</span> &#123;</span>
    background-color: red;
  &#125;
<span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></code></pre></div>

<h5 id="9-如果特性元素较多，应该主动换行。"><a href="#9-如果特性元素较多，应该主动换行。" class="headerlink" title="9) 如果特性元素较多，应该主动换行。"></a>9) 如果特性元素较多，应该主动换行。</h5><p>正例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">MyComponent</span> <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span></span>
<span class="hljs-tag">    <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span></span>
<span class="hljs-tag">    <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span></span>
<span class="hljs-tag"> /&gt;</span></code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">MyComponent</span> <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span> <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span> <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span> <span class="hljs-attr">foo</span>=<span class="hljs-string">"a"</span> <span class="hljs-attr">bar</span>=<span class="hljs-string">"b"</span> <span class="hljs-attr">baz</span>=<span class="hljs-string">"c"</span>/&gt;</span></code></pre></div>

<h4 id="2-1-2-模板中使用简单的表达式"><a href="#2-1-2-模板中使用简单的表达式" class="headerlink" title="2.1.2. 模板中使用简单的表达式"></a>2.1.2. 模板中使用简单的表达式</h4><p>组件模板应该只包含简单的表达式，复杂的表达式则应该重构为计算属性或方法。复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该出现的是什么，而非如何计算那个值。而且计算属性和方法使得代码可以重用。</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript">&lt;template&gt;
  &lt;p&gt;&#123;&#123; normalizedFullName &#125;&#125;&lt;<span class="hljs-regexp">/p&gt;</span>
<span class="hljs-regexp">&lt;/</span>template&gt;

<span class="hljs-comment">// 复杂表达式已经移入一个计算属性</span>
computed: &#123;
  normalizedFullName: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.fullName.split(<span class="hljs-string">' '</span>).map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">word</span>) </span>&#123;
      <span class="hljs-keyword">return</span> word[<span class="hljs-number">0</span>].toUpperCase() + word.slice(<span class="hljs-number">1</span>)
    &#125;).join(<span class="hljs-string">' '</span>)
  &#125;
&#125;</code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs javascript">&lt;template&gt;
  &lt;p&gt;
       &#123;&#123;
          fullName.split(<span class="hljs-string">' '</span>).map(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">word</span>) </span>&#123;
             <span class="hljs-keyword">return</span> word[<span class="hljs-number">0</span>].toUpperCase() + word.slice(<span class="hljs-number">1</span>)
           &#125;).join(<span class="hljs-string">' '</span>)
        &#125;&#125;
  &lt;<span class="hljs-regexp">/p&gt;</span>
<span class="hljs-regexp">&lt;/</span>template&gt;</code></pre></div>

<h4 id="2-1-3-指令都使用缩写形式"><a href="#2-1-3-指令都使用缩写形式" class="headerlink" title="2.1.3 指令都使用缩写形式"></a>2.1.3 指令都使用缩写形式</h4><p>指令推荐都使用缩写形式，(用 : 表示 v-bind: 、用 @ 表示 v-on: 和用 # 表示 v-slot:)</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span></span>
<span class="hljs-tag">  @<span class="hljs-attr">input</span>=<span class="hljs-string">"onInput"</span></span>
<span class="hljs-tag">  @<span class="hljs-attr">focus</span>=<span class="hljs-string">"onFocus"</span></span>
<span class="hljs-tag">&gt;</span></code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">input</span></span>
<span class="hljs-tag">  <span class="hljs-attr">v-on:input</span>=<span class="hljs-string">"onInput"</span></span>
<span class="hljs-tag">  @<span class="hljs-attr">focus</span>=<span class="hljs-string">"onFocus"</span></span>
<span class="hljs-tag">&gt;</span></code></pre></div>

<h4 id="2-1-4-标签顺序保持一致"><a href="#2-1-4-标签顺序保持一致" class="headerlink" title="2.1.4 标签顺序保持一致"></a>2.1.4 标签顺序保持一致</h4><p>单文件组件应该总是让标签顺序保持为 `</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></code></pre></div>

<p>反例：</p>
<div class="hljs"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span>...<span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre></div>

<h4 id="2-1-5-必须为-v-for-设置键值-key"><a href="#2-1-5-必须为-v-for-设置键值-key" class="headerlink" title="2.1.5 必须为 v-for 设置键值 key"></a>2.1.5 必须为 v-for 设置键值 key</h4><h4 id="2-1-6-v-show-与-v-if-选择"><a href="#2-1-6-v-show-与-v-if-选择" class="headerlink" title="2.1.6 v-show 与 v-if 选择"></a>2.1.6 v-show 与 v-if 选择</h4><p>如果运行时，需要非常频繁地切换，使用 v-show ；如果在运行时，条件很少改变，使用 v-if。</p>
<h4 id="2-1-7-script-标签内部结构顺序"><a href="#2-1-7-script-标签内部结构顺序" class="headerlink" title="2.1.7 script 标签内部结构顺序"></a>2.1.7 script 标签内部结构顺序</h4><p>components &gt; props &gt; data &gt; computed &gt; watch &gt; filter &gt; 钩子函数（钩子函数按其执行顺序） &gt; methods</p>
<h4 id="2-1-8-Vue-Router-规范"><a href="#2-1-8-Vue-Router-规范" class="headerlink" title="2.1.8 Vue Router 规范"></a>2.1.8 Vue Router 规范</h4><h5 id="1-页面跳转数据传递使用路由参数"><a href="#1-页面跳转数据传递使用路由参数" class="headerlink" title="1) 页面跳转数据传递使用路由参数"></a>1) 页面跳转数据传递使用路由参数</h5><p>页面跳转，例如 A 页面跳转到 B 页面，需要将 A 页面的数据传递到 B 页面，推荐使用 路由参数进行传参，而不是将需要传递的数据保存 vuex，然后在 B 页面取出 vuex 的数据，因为如果在 B 页面刷新会导致 vuex 数据丢失，导致 B 页面无法正常显示数据。</p>
<p>正例：</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> id = <span class="hljs-string">' 123'</span>;
<span class="hljs-keyword">this</span>.$router.push(&#123; <span class="hljs-attr">name</span>: <span class="hljs-string">'userCenter'</span>, <span class="hljs-attr">query</span>: &#123; <span class="hljs-attr">id</span>: id &#125; &#125;);</code></pre></div>

<h5 id="2-使用路由懒加载（延迟加载）机制"><a href="#2-使用路由懒加载（延迟加载）机制" class="headerlink" title="2) 使用路由懒加载（延迟加载）机制"></a>2) 使用路由懒加载（延迟加载）机制</h5><div class="hljs"><pre><code class="hljs javascript">&#123;
    path: <span class="hljs-string">'/uploadAttachment'</span>,
    name: <span class="hljs-string">'uploadAttachment'</span>,
    meta: &#123;
      title: <span class="hljs-string">'上传附件'</span>
    &#125;,
    component: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/view/components/uploadAttachment/index.vue'</span>)
  &#125;,</code></pre></div>

<h5 id="3-router-中的命名规范"><a href="#3-router-中的命名规范" class="headerlink" title="3) router 中的命名规范"></a>3) router 中的命名规范</h5><p>path、childrenPoints 命名规范采用<code>kebab-case</code>命名规范（尽量 vue 文件的目录结构保持一致，因为目录、文件名都是<code>kebab-case</code>，这样很方便找到对应的文件）</p>
<p>name 命名规范采用<code>KebabCase</code>命名规范且和 component 组件名保持一致！（因为要保持 keep-alive 特性，keep-alive 按照 component 的 name 进行缓存，所以两者必须高度保持一致）</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-comment">// 动态加载</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> reload = [
  &#123;
    path: <span class="hljs-string">'/reload'</span>,
    name: <span class="hljs-string">'reload'</span>,
    component: Main,
    meta: &#123;
      title: <span class="hljs-string">'动态加载'</span>,
      icon: <span class="hljs-string">'icon iconfont'</span>
    &#125;,

    children: [
      &#123;
        path: <span class="hljs-string">'/reload/smart-reload-list'</span>,
        name: <span class="hljs-string">'SmartReloadList'</span>,
        meta: &#123;
          title: <span class="hljs-string">'SmartReload'</span>,
          childrenPoints: [
            &#123;
              title: <span class="hljs-string">'查询'</span>,
              name: <span class="hljs-string">'smart-reload-search'</span>
            &#125;,
            &#123;
              title: <span class="hljs-string">'执行reload'</span>,
              name: <span class="hljs-string">'smart-reload-update'</span>
            &#125;,
            &#123;
              title: <span class="hljs-string">'查看执行结果'</span>,
              name: <span class="hljs-string">'smart-reload-result'</span>
            &#125;
          ]
        &#125;,
        component: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span>
          <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/views/reload/smart-reload/smart-reload-list.vue'</span>)
      &#125;
    ]
  &#125;
];</code></pre></div>

<h5 id="4-router-中的-path-命名规范"><a href="#4-router-中的-path-命名规范" class="headerlink" title="4) router 中的 path 命名规范"></a>4) router 中的 path 命名规范</h5><p>path 除了采用<code>kebab-case</code>命名规范以外，必须以 / 开头，即使是 children 里的 path 也要以 / 开头。如下示例</p>
<p>-</p>
<p>目的：</p>
<p>经常有这样的场景：某个页面有问题，要立刻找到这个 vue 文件，如果不用以/开头，path 为 parent 和 children 组成的，可能经常需要在 router 文件里搜索多次才能找到，而如果以/开头，则能立刻搜索到对应的组件 *</p>
<div class="hljs"><pre><code class="hljs javascript">&#123;
    path: <span class="hljs-string">'/file'</span>,
    name: <span class="hljs-string">'File'</span>,
    component: Main,
    meta: &#123;
      title: <span class="hljs-string">'文件服务'</span>,
      icon: <span class="hljs-string">'ios-cloud-upload'</span>
    &#125;,
    children: [
      &#123;
        path: <span class="hljs-string">'/file/file-list'</span>,
        name: <span class="hljs-string">'FileList'</span>,
        component: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/views/file/file-list.vue'</span>)
      &#125;,
      &#123;
        path: <span class="hljs-string">'/file/file-add'</span>,
        name: <span class="hljs-string">'FileAdd'</span>,
        component: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/views/file/file-add.vue'</span>)
      &#125;,
      &#123;
        path: <span class="hljs-string">'/file/file-update'</span>,
        name: <span class="hljs-string">'FileUpdate'</span>,
        component: <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-keyword">import</span>(<span class="hljs-string">'@/views/file/file-update.vue'</span>)
      &#125;
    ]
  &#125;</code></pre></div>

<h3 id="二-Vue-项目目录规范"><a href="#二-Vue-项目目录规范" class="headerlink" title="(二) Vue 项目目录规范"></a>(二) Vue 项目目录规范</h3><h4 id="2-2-1-基础"><a href="#2-2-1-基础" class="headerlink" title="2.2.1 基础"></a>2.2.1 基础</h4><p>vue 项目中的所有命名一定要与后端命名统一。</p>
<p>比如权限：后端 privilege, 前端无论 router , store, api 等都必须使用 privielege 单词！</p>
<h4 id="2-2-2-使用-Vue-cli-脚手架"><a href="#2-2-2-使用-Vue-cli-脚手架" class="headerlink" title="2.2.2 使用 Vue-cli 脚手架"></a>2.2.2 使用 Vue-cli 脚手架</h4><p>使用 vue-cli3 来初始化项目，项目名按照上面的命名规范。</p>
<h4 id="2-2-3-目录说明"><a href="#2-2-3-目录说明" class="headerlink" title="2.2.3 目录说明"></a>2.2.3 目录说明</h4><p>目录名按照上面的命名规范，其中 components 组件用大写驼峰，其余除 components 组件目录外的所有目录均使用 kebab-case 命名。</p>
<div class="hljs"><pre><code class="hljs css"><span class="hljs-selector-tag">src</span>                               源码目录
|-- api                              所有api接口
|-- assets                           静态资源，images, icons, styles等
|-- components                       公用组件
|-- config                           配置信息
|-- constants                        常量信息，项目所有Enum, 全局常量等
|-- directives                       自定义指令
|-- filters                          过滤器，全局工具
|-- datas                            模拟数据，临时存放
|-- lib                              外部引用的插件存放及修改文件
|-- mock                             模拟接口，临时存放
|-- plugins                          插件，全局使用
|-- router                           路由，统一管理
|-- store                            vuex, 统一管理
|-- themes                           自定义样式主题
|-- views                            视图目录
|   |-- role                             role模块名
|   |-- |-- role-list.vue                    role列表页面
|   |-- |-- role-add.vue                     role新建页面
|   |-- |-- role-update.vue                  role更新页面
|   |-- |-- index.less                      role模块样式
|   |-- |-- components                      role模块通用组件文件夹
|   |-- employee                         employee模块</code></pre></div>

<h5 id="1-api-目录"><a href="#1-api-目录" class="headerlink" title="1) api 目录"></a>1) api 目录</h5><ul>
<li>文件、变量命名要与后端保持一致。</li>
<li>此目录对应后端 API 接口，按照后端一个 controller 一个 api js 文件。若项目较大时，可以按照业务划分子目录，并与后端保持一致。</li>
<li>api 中的方法名字要与后端 api url 尽量保持语义高度一致性。</li>
<li>对于 api 中的每个方法要添加注释，注释与后端 swagger 文档保持一致。</li>
</ul>
<p>正例：</p>
<p>后端 url： EmployeeController.java</p>
<div class="hljs"><pre><code class="hljs java">/employee/add
/employee/delete/&#123;id&#125;
/employee/update</code></pre></div>

<p>前端： employee.js</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-comment">// 添加员工</span>
addEmployee: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> &#123;
  <span class="hljs-keyword">return</span> postAxios(<span class="hljs-string">'/employee/add'</span>, data)
&#125;,
<span class="hljs-comment">// 更新员工信息</span>
updateEmployee: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> &#123;
  <span class="hljs-keyword">return</span> postAxios(<span class="hljs-string">'/employee/update'</span>, data)
&#125;,
  <span class="hljs-comment">// 删除员工</span>
deleteEmployee: <span class="hljs-function">(<span class="hljs-params">employeeId</span>) =&gt;</span> &#123;
  <span class="hljs-keyword">return</span> postAxios(<span class="hljs-string">'/employee/delete/'</span> + employeeId)
 &#125;,</code></pre></div>

<h5 id="2-assets-目录"><a href="#2-assets-目录" class="headerlink" title="2) assets 目录"></a>2) assets 目录</h5><p>assets 为静态资源，里面存放 images, styles, icons 等静态资源，静态资源命名格式为 kebab-case</p>
<div class="hljs"><pre><code class="hljs css">|assets
|-- icons
|-- images
|   |-- background-color.png
|   |-- upload-header.png
|-- styles</code></pre></div>

<h5 id="3-components-目录"><a href="#3-components-目录" class="headerlink" title="3) components 目录"></a>3) components 目录</h5><p>此目录应按照组件进行目录划分，目录命名为 KebabCase，组件命名规则也为 KebabCase</p>
<div class="hljs"><pre><code class="hljs css">|components
|-- error-log
|   |-- index.vue
|   |-- index.less
|-- markdown-editor
|   |-- index.vue
|   |-- index.js
|-- kebab-case</code></pre></div>

<h5 id="4-constants-目录"><a href="#4-constants-目录" class="headerlink" title="4) constants 目录"></a>4) constants 目录</h5><p>此目录存放项目所有常量，如果常量在 vue 中使用，请使用 vue-enum 插件(<a href="https://www.npmjs.com/package/vue-enum" target="_blank" rel="noopener">https://www.npmjs.com/package/vue-enum</a>)</p>
<p>目录结构：</p>
<div class="hljs"><pre><code class="hljs css">|constants
|-- index.js
|-- role.js
|-- employee.js</code></pre></div>

<p>例子： employee.js</p>
<div class="hljs"><pre><code class="hljs javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> EMPLOYEE_STATUS = &#123;
  NORMAL: &#123;
    value: <span class="hljs-number">1</span>,
    desc: <span class="hljs-string">'正常'</span>
  &#125;,
  DISABLED: &#123;
    value: <span class="hljs-number">1</span>,
    desc: <span class="hljs-string">'禁用'</span>
  &#125;,
  DELETED: &#123;
    value: <span class="hljs-number">2</span>,
    desc: <span class="hljs-string">'已删除'</span>
  &#125;
&#125;;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> EMPLOYEE_ACCOUNT_TYPE = &#123;
  QQ: &#123;
    value: <span class="hljs-number">1</span>,
    desc: <span class="hljs-string">'QQ登录'</span>
  &#125;,
  WECHAT: &#123;
    value: <span class="hljs-number">2</span>,
    desc: <span class="hljs-string">'微信登录'</span>
  &#125;,
  DINGDING: &#123;
    value: <span class="hljs-number">3</span>,
    desc: <span class="hljs-string">'钉钉登录'</span>
  &#125;,
  USERNAME: &#123;
    value: <span class="hljs-number">4</span>,
    desc: <span class="hljs-string">'用户名密码登录'</span>
  &#125;
&#125;;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;
  EMPLOYEE_STATUS,
  EMPLOYEE_ACCOUNT_TYPE
&#125;;</code></pre></div>

<h5 id="5-router-与-store-目录"><a href="#5-router-与-store-目录" class="headerlink" title="5) router 与 store 目录"></a>5) router 与 store 目录</h5><p>这两个目录一定要将业务进行拆分，不能放到一个 js 文件里。</p>
<p>router 尽量按照 views 中的结构保持一致</p>
<p>store 按照业务进行拆分不同的 js 文件</p>
<h5 id="6-views-目录"><a href="#6-views-目录" class="headerlink" title="6) views 目录"></a>6) views 目录</h5><ul>
<li>命名要与后端、router、api 等保持一致</li>
<li>components 中组件要使用 PascalCase 规则</li>
</ul>
<div class="hljs"><pre><code class="hljs css">|-- views                            视图目录
|   |-- role                             role模块名
|   |   |-- role-list.vue                    role列表页面
|   |   |-- role-add.vue                     role新建页面
|   |   |-- role-update.vue                  role更新页面
|   |   |-- index.less                      role模块样式
|   |   |-- components                      role模块通用组件文件夹
|   |   |   |-- role-header.vue                        role头部组件
|   |   |   |-- role-modal.vue                         role弹出框组件
|   |-- employee                         employee模块
|   |-- behavior-log                      行为日志log模块
|   |-- code-generator                    代码生成器模块</code></pre></div>

<h4 id="2-2-4-注释说明"><a href="#2-2-4-注释说明" class="headerlink" title="2.2.4 注释说明"></a>2.2.4 注释说明</h4><p>整理必须加注释的地方</p>
<ul>
<li>公共组件使用说明</li>
<li>api 目录的接口 js 文件必须加注释</li>
<li>store 中的 state, mutation, action 等必须加注释</li>
<li>vue 文件中的 template 必须加注释，若文件较大添加 start end 注释</li>
<li>vue 文件的 methods，每个 method 必须添加注释</li>
<li>vue 文件的 data, 非常见单词要加注释</li>
</ul>
<h4 id="2-2-5-其他"><a href="#2-2-5-其他" class="headerlink" title="2.2.5 其他"></a>2.2.5 其他</h4><h5 id="1-尽量不要手动操作-DOM"><a href="#1-尽量不要手动操作-DOM" class="headerlink" title="1) 尽量不要手动操作 DOM"></a>1) 尽量不要手动操作 DOM</h5><p>因使用 vue 框架，所以在项目开发中尽量使用 vue 的数据驱动更新 DOM，尽量（不到万不得已）不要手动操作 DOM，包括：增删改 dom 元素、以及更改样式、添加事件等。</p>
<h5 id="2-删除无用代码"><a href="#2-删除无用代码" class="headerlink" title="2) 删除无用代码"></a>2) 删除无用代码</h5><p>因使用了 git/svn 等代码版本工具，对于无用代码必须及时删除，例如：一些调试的 console 语句、无用的弃用功能代码。</p>

            </article>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                
              </div>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" target="_blank" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <div class="post-prev col-6">
                    
                    
                  </div>
                  <div class="post-next col-6">
                    
                    
                      <a href="/blog/2020/06/26/CSS%E5%AE%9E%E7%8E%B0%E5%A4%9A%E8%A1%8C%E6%96%87%E6%9C%AC%E6%BA%A2%E5%87%BA%E7%9C%81%E7%95%A5/">
                        <span class="hidden-mobile">CSS实现多行文本溢出省略</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </div>
                </div>
              
            </div>

            
              <!-- Comments -->
              <div class="comments" id="comments">
                
                

              </div>
            
          </div>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a id="scroll-top-button" href="#" role="button">
      <i class="iconfont icon-arrowup" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  

  <footer class="mt-5">
  <div class="text-center py-3">
    <div>
      <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a>
      <i class="iconfont icon-love"></i>
      <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener">
        <span>Fluid</span></a>
    </div>
    

    

    
  </div>
</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="/blog/js/debouncer.js" ></script>
<script  src="/blog/js/main.js" ></script>

<!-- Plugins -->


  
    <script  src="/blog/js/lazyload.js" ></script>
  



  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/blog/js/clipboard-use.js" ></script>



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>





  <script  src="https://cdn.staticfile.org/tocbot/4.11.1/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;

      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: 'article.markdown-body',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        collapseDepth: 0,
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc').css('visibility', 'visible');
      }
    });
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "前端开发规范&nbsp;",
      ],
      cursorChar: "|",
      typeSpeed: 70,
      loop: true,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/blog/js/local-search.js" ></script>
  <script>
    var path = "/blog/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      searchFunc(path, 'local-search-input', 'local-search-result');
      this.onclick = null
    }
  </script>



  <script  src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />

  <script>
    $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]').each(
      function () {
        var element = document.createElement('a');
        $(element).attr('data-fancybox', 'images');
        $(element).attr('href', $(this).attr('src'));
        $(this).wrap(element);
      }
    );
  </script>







  
  
    <script>
      !function (e, t, a) {
        function r() {
          for (var e = 0; e < s.length; e++) s[e].alpha <= 0 ? (t.body.removeChild(s[e].el), s.splice(e, 1)) : (s[e].y--, s[e].scale += .004, s[e].alpha -= .013, s[e].el.style.cssText = "left:" + s[e].x + "px;top:" + s[e].y + "px;opacity:" + s[e].alpha + ";transform:scale(" + s[e].scale + "," + s[e].scale + ") rotate(45deg);background:" + s[e].color + ";z-index:99999");
          requestAnimationFrame(r)
        }

        function n() {
          var t = "function" == typeof e.onclick && e.onclick;
          e.onclick = function (e) {
            t && t(), o(e)
          }
        }

        function o(e) {
          var a = t.createElement("div");
          a.className = "heart", s.push({
            el: a,
            x: e.clientX - 5,
            y: e.clientY - 5,
            scale: 1,
            alpha: 1,
            color: c()
          }), t.body.appendChild(a)
        }

        function i(e) {
          var a = t.createElement("style");
          a.type = "text/css";
          try {
            a.appendChild(t.createTextNode(e))
          } catch (t) {
            a.styleSheet.cssText = e
          }
          t.getElementsByTagName("head")[0].appendChild(a)
        }

        function c() {
          return "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"
        }

        var s = [];
        e.requestAnimationFrame = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function (e) {
          setTimeout(e, 1e3 / 60)
        }, i(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"), n(), r()
      }(window, document);
    </script>
  













</body>
</html>
